package simi;

import java.io.BufferedReader;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.StringReader;

public class ExpressionEvaluator {
	private static String[] prompts = SimiPropertyManager.getConfig().getStringArray("sessionpage.prompt");
	private InputStream rInputStream;
	private OutputStream OutputStream;
	private ByteArrayOutputStream Output;

	public ExpressionEvaluator() {
		super();
	}

	public InputStream getRInputStream() {
		return rInputStream;
	}

	public void setRInputStream(InputStream is) {
		this.rInputStream = is;
	}

	public OutputStream getROutputStream() {
		return OutputStream;
	}

	public void setROutputStream(OutputStream os) {
		this.OutputStream = os;
	}

	public ByteArrayOutputStream getROutput() {
		return Output;
	}

	public void setROutput(ByteArrayOutputStream is) {
		this.Output = is;
	}

	public String rEval(String expression) throws IOException {

		StringBuffer theOutput = new StringBuffer();
		BufferedReader reader = new BufferedReader(new StringReader(expression));

		try {
			String str = null;
			while ((str = reader.readLine()) != null) {
				str = str.trim();
				if (str.length() > 0) {
					String Output = rEvalLine(str);
					if (Output != null && Output.length() > 0) {
						theOutput.append(Output);
					}
				}
			}
		} catch (IOException ie) {
			theOutput.append(ie.getMessage());
			theOutput.append(Constants.BR_TAG);
		}

		return theOutput.toString();
	}

	private void writeToOutput(String cmd) throws IOException {

		OutputStream.write(cmd.getBytes());
		OutputStream.flush();
	}

	public String rEvalLine(String expLine) throws IOException {

		String theResult = null;

		// Get current Output
		String currentOutput = Output.toString();
		currentOutput = SimiUtils.fixROutput(currentOutput);

		// Now push in expression
		expLine = SimiUtils.fixRInput(expLine);
		writeToOutput(expLine);

		// Now read until we have an answer
		boolean prompted = false;
		while (!prompted) {
			String newOutput = Output.toString();
			newOutput = SimiUtils.fixROutput(newOutput);
			for (String prompt: prompts){
				if (newOutput.length() > currentOutput.length()&& newOutput.trim().endsWith(prompt)) {
					theResult = newOutput.substring(currentOutput.length());
					theResult.trim();
					theResult = theResult.substring(0, theResult.lastIndexOf(prompt));
					theResult = theResult + Constants.BR_TAG;
					prompted = true;
					break;
				}
			}
		}
		return theResult;
	}
}